package com.example.theoretical_verification.thread;

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadLocalExample03 {

    // 定义一个ThreadLocal对象来存储用户信息
    // 其实，表面上看这个变量定义在测试类这里，作为各个线程的全局变量。其实，它的底层实现，是每个线程里面最后都会有一个局部变量的。不要给它的写法骗了。
    private static ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<>();

    // AtomicInteger用于生成用户ID
    private static AtomicInteger nextUserId = new AtomicInteger(1);

    // 用户信息类
    static class UserInfo {
        private int userId;
        private String username;

        public UserInfo(String username) {
            this.userId = nextUserId.getAndIncrement();
            this.username = username;
        }

        public int getUserId() {
            return userId;
        }

        public String getUsername() {
            return username;
        }
    }

    // 设置当前线程的用户信息
    public static void setCurrentUser(String username) {
        // 就这依据，一下子把id、name都设置进去了
        userInfoThreadLocal.set(new UserInfo(username));
    }

    // 获取当前线程的用户信息
    public static UserInfo getCurrentUser() {
        return userInfoThreadLocal.get();
    }

    // 清除当前线程的用户信息
    public static void clearCurrentUser() {
        userInfoThreadLocal.remove();
    }

    public static void main(String[] args) {
        // 模拟多个线程访问应用，每个线程都设置自己的用户信息
        for (int i = 0; i < 20; i++) {
            final int userId = i;
            new Thread(() -> {
                // 设置当前线程的用户信息
                setCurrentUser("User_" + userId);
                // 获取当前线程的用户信息并打印
                UserInfo currentUser = getCurrentUser();
                System.out.println("Thread " + Thread.currentThread().getId() +
                        " - User ID: " + currentUser.getUserId() +
                        ", Username: " + currentUser.getUsername());
                // 清除当前线程的用户信息
                clearCurrentUser();
            }).start();
        }
    }
}

